package com.kitty.game.fight.service;

import com.kitty.game.fight.SkillConst;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.bean.FightObject;
import com.kitty.game.fight.pet.PetSkillProcessor;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.service.PetUtils;
import com.kitty.game.role.model.Role;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.listener.event.LogoutEvent;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 各种计算类Service
 */
@Service
@Slf4j
public class CountService {

    @Autowired
    private FightService fightService;

    /**
     * 登出
     */
    @EventHandler(EventType.LOGOUT)
    public void handleLogoutEvent(LogoutEvent logoutEvent) {
        Role role = logoutEvent.getRole();
        /**计算一下角色的总属性 排行榜用*/
        role.setPhyPower(role.getMaxPhyPower());
        role.setMagPower(role.getMaxMagPower());
        role.setDefense(role.getMaxDefense());
        role.setSpeed(role.getMaxSpeed());
        role.save();
    }


    /**
     * 气血公式
     */
    public int countLife(int level, int wood, int con) {
        return new Double((con * 0.415 + 25) * level + 75 + (5 + level * 0.268) * level + (wood * 1.22 * con)).intValue();
    }

    /**
     * 总气血
     */
    public int countMaxLife(Role role) {
        int totalWood = role.getWood() + role.getExtraWood();
        int totalCon = role.getExtendBox().getBasicAttrib().getCon() + role.getCon() + role.getExtraCon();
        return countLife(role.getLevel(), totalWood, totalCon);
    }

    /**
     * 增益气血
     */
    public int countExtraLife(Role role) {
        return countMaxLife(role) - countBasicLife(role);
    }

    /**
     * 基础气血
     */
    public int countBasicLife(Role role) {
        return countLife(role.getLevel(), role.getWood(), role.getExtendBox().getBasicAttrib().getCon() + role.getCon());
    }

    /**
     * 速度计算公式
     */
    public int countSpeed(int fire, int dex) {
        return new Double((dex * fire * 0.0237) + (double)(2 * dex) + 48).intValue();
    }

    /**
     * 总速度
     */
    public int countMaxSpeed(Role role) {
        int totalFire = role.getFire() + role.getExtraFire();
        int totalDex = role.getExtendBox().getBasicAttrib().getDex() + role.getDex() + role.getExtraDex();
        return (int)((double)(this.countSpeed(totalFire, totalDex) * role.getZhuque()));
    }

    /**
     * 增益速度
     */
    public int countExtraSpeed(Role role) {
        return countMaxSpeed(role) - countBasicSpeed(role);
    }

    /**
     * 基础速度
     */
    public int countBasicSpeed(Role role) {
        return (int)((double)(this.countSpeed(role.getFire(), role.getExtendBox().getBasicAttrib().getDex() + role.getDex())));
    }

    /**
     * 物攻计算公式
     */
    public int countPhyPower(int earth, int str) {
        return new Double((str * earth * 0.553) + 5 * str + 40).intValue();
    }

    /**
     * 总物攻
     */
    public int countMaxPhyPower(Role role) {
        int totalEarth = role.getEarth() + role.getExtraEarth();
        int totalStr = role.getExtendBox().getBasicAttrib().getStr() + role.getStr() + role.getExtraStr();

        return (int)(countPhyPower(totalEarth, totalStr)* role.getBaihu());
    }

    /**
     * 增益物攻
     */
    public int countExtraPhyPower(Role role) {
        return countMaxPhyPower(role) - countBasicPhyPower(role);
    }

    /**
     * 基础物攻
     */
    public int countBasicPhyPower(Role role) {
        return countPhyPower(role.getEarth(), role.getExtendBox().getBasicAttrib().getStr() + role.getStr());
    }


    /**
     * 法攻计算公式
     */
    public int countMagPower(int metal, int wiz) {
        return new Double((wiz * metal * 0.34) + 5 * wiz + 40).intValue();
    }

    /**
     * 总法攻
     */
    public int countMaxMagPower(Role role) {
        int totalMetal = role.getMetal() + role.getExtraMetal();
        int totalWiz = role.getExtendBox().getBasicAttrib().getWiz() + role.getWiz() + role.getExtraWiz();
        return (int)(countMagPower(totalMetal, totalWiz)*role.getQinglong());
    }

    /**
     * 增益法攻
     */
    public int countExtraMagPower(Role role) {
        return countMaxMagPower(role) - countBasicMagPower(role);
    }

    /**
     * 基础法攻
     */
    public int countBasicMagPower(Role role) {
        return countMagPower(role.getMetal(), role.getExtendBox().getBasicAttrib().getWiz() + role.getWiz());
    }

    /**
     * 防御计算公式
     */
    public int countDefense(int water, int con) {
        return new Double((con * water * 0.257) + 5 * con + 20).intValue();
    }

    /**
     * 总防御
     */
    public int countMaxDefense(Role role) {
        int totalCon = role.getExtendBox().getBasicAttrib().getCon() + role.getCon() + role.getExtraCon();
        int totalWater = role.getWater() + role.getExtraWater();
        return (int)(countDefense(totalWater, totalCon)*role.getXuanwu());
    }

    /**
     * 增益防御
     */
    public int countExtraDefense(Role role) {
        return countMaxDefense(role) - countBasicDefense(role);
    }

    /**
     * 基础防御
     */
    public int countBasicDefense(Role role) {
        return countDefense(role.getWater(), role.getExtendBox().getBasicAttrib().getCon() + role.getCon());
    }

    /**
     * 法力计算公式
     */
    public int countMana(int wood, int wiz, int level) {
        return new Double((wiz * 0.305 + 24) * level + 60 + (5 + level * 0.228) * level + (wood * 1.01 * wiz)).intValue();
    }

    /**
     * 总法力
     */
    public int countMaxMana(Role role) {
        int totalWood = role.getWood() + role.getExtraWood();
        int totalWiz = role.getExtendBox().getBasicAttrib().getWiz() + role.getWiz() + role.getExtraWiz();
        return countMana(totalWood, totalWiz, role.getLevel());
    }

    /**
     * 增益法力
     */
    public int countExtraMana(Role role) {
        return countMaxMana(role) - countBasicMana(role);
    }

    /**
     * 基础法力
     */
    public int countBasicMana(Role role) {
        return countMana(role.getWood(), role.getExtendBox().getBasicAttrib().getWiz() + role.getWiz(), role.getLevel());
    }


    /**
     * 宠物气血
     */
    public int countPetLife(int level, int con, int lifeEffect) {
        return new Double((1.397 * level * Math.round(1.285 * level + 123) + Math.round(level / 3.5 + 4) * con * 1.6) * (0.00625 * lifeEffect + 0.375)).intValue();
    }

    /**
     * 宠物法力
     */
    public int countPetMana(int level, int wiz, int manaEffect) {
        return new Double((Math.round(1.1876 * level + 70) * level + Math.round(level / 5.3 + 4) * wiz * 1.6) * (0.00625 * manaEffect + 0.375)).intValue();
    }


    /**
     * 官服的宠物物理伤害计算
     */
    public int countPetPhyPower(int petLevel, int str, int phyShape) {
        int phyEffect = phyShape - 40;
        double levelFactor = Math.floor(petLevel / 4);
        if (levelFactor > 30.0) {
            levelFactor = 30.0;
        }
        double rawValue = Math.floor((str * levelFactor * 5.0 * 4.0 / 42.0 + str * 5.0) * 2.0 * (1.0 + phyEffect / 100.0) + 100);

        double phyFactor = 0.63 + 0.01 * (petLevel - 1);
        if (phyFactor > 1.0) {
            phyFactor = 1.0;
        }
        return (int) Math.floor(rawValue * phyFactor);
    }

    /**
     * 官服的宠物法术伤害计算
     */
    public int countPetMagPower(int petLevel, int wiz, int magShape) {
        int magEffect = magShape - 40;
        double levelFactor = Math.floor(petLevel / 4);
        if (levelFactor > 30.0) {
            levelFactor = 30.0;
        }
        return (int) Math.floor(1.3 * (wiz * levelFactor * 5.0 * 4.0 / 42.0 + wiz * 5.0) * 2.0 * (1.0 + magEffect / 100.0) + 100);

    }

    /**
     * 宠物速度
     */
    public int countPetSpeed(int level, int dex, int speedEffect) {
        return (int) Math.round(dex * 2.0 + dex * speedEffect * level * 0.2 / 420.0 + 48);
    }

    /**
     * 宠物防御
     */
    public int countPetDefense(int level, int con, int lifeEffect) {
        return (int) Math.round(level * 40.0 + con * 5.0 +(int)(lifeEffect * 0.22));
    }

    /**
     * 取宠物总气血
     */
    public int countPetMaxLife(Pet pet) {
        return (countPetLife(pet.getLevel(), pet.getCon() + pet.getBasicAttrib().getCon(), pet.getTotalLifeEffect()) + pet.getExtraLife())*2  + pet.getBookExtraLife() + PetUtils.getPeiYuanAddInfo("max_life",pet.getPeiyuan_add_info());
    }

    /**
     * 取宠物总法力
     */
    public int countPetMaxMana(Pet pet) {
        return (countPetMana(pet.getLevel(), pet.getWiz() + pet.getBasicAttrib().getWiz(), pet.getTotalManaEffect()) + pet.getExtraMana())*2;

    }

    /**
     * 取宠物总速度
     */
    public int countPetMaxSpeed(Pet pet) {
        return (int) ((countPetSpeed(pet.getLevel(), pet.getDex() + pet.getBasicAttrib().getDex(), pet.getTotalSpeedEffect())* pet.getZhuque() + pet.getExtraSpeed() )*1.2) + pet.getBookExtraSpeed()  + pet.getluoshuSpeed() + PetUtils.getPeiYuanAddInfo("speed",pet.getPeiyuan_add_info());
    }

    /**
     * 取宠物总物攻
     */
    public int countPetMaxPhyPower(Pet pet) {
        return (int) ((countPetPhyPower(pet.getLevel(), pet.getStr() + pet.getBasicAttrib().getStr(), pet.getTotalPhyEffect()) * pet.getBaihu() + pet.getExtraPhyPower() ) * (1.0 + pet.getExtraAttr().getDouble("attack")))*2+ pet.getBookExtraPhyPower() + pet.getluoshuPhypower()+PetUtils.getPeiYuanAddInfo("phy_power",pet.getPeiyuan_add_info());
    }

    /**
     * 取宠物总法攻
     */
    public int countPetMaxMagPower(Pet pet) {
        return (int) ((countPetMagPower(pet.getLevel(), pet.getWiz() + pet.getBasicAttrib().getWiz(), pet.getTotalMagEffect()) * pet.getQinglong() + pet.getExtraMagPower()) * (1.0 + pet.getExtraAttr().getDouble("attack")))*2  + pet.getBookExtraMagPower() + pet.getluoshuMagpower()+PetUtils.getPeiYuanAddInfo("mag_power",pet.getPeiyuan_add_info());
    }

    /**
     * 取宠物总防御
     */
    public int countPetMaxDefense(Pet pet) {
        return (int) ((countPetDefense(pet.getLevel(), pet.getCon() + pet.getBasicAttrib().getCon(), pet.getTotalLifeEffect()) + pet.getExtraDefense()) * pet.getXuanwu() * (1.0 + pet.getExtraAttr().getDouble("def")))*2   + pet.getBookExtraDefense() + pet.getluoshuDefense() + PetUtils.getPeiYuanAddInfo("def",pet.getPeiyuan_add_info());
    }

    /**
     * 战斗计算伤害
     */
    public int countHurt(Fight fight, FightObject attacker, FightObject target, boolean isPenetrate) {
        //伤害加成
        double hurtAddition = 0.0;
        // 随机伤害
        int hurt = 0;
        boolean confusion = attacker.isConfusion();
        if (target.isFrozen()) {
            return hurt;/**如果目标是冰冻状态 伤害直接返回0*/
        }

        RoleSkill skill = attacker.getSkillBy(attacker.getSkillId());
        if (!target.isFallDown()) {
            if (skill != null && skill.getSkillId() != 2 && skill.getSkillId() != 501) {
                hurt = attacker.getMagHurt(target, isPenetrate);
            } else {
                hurt = attacker.getPhyHurt(target, isPenetrate);
            }
        } else {
//            logger.error("计算伤害报错=目标死亡了={}", new IllegalStateException().getMessage());
        }
        if (!confusion) {
            if (fightService.isSameTeam(attacker, target)) {
                hurt = 1;
            }
        }
        /**防御状态物攻伤害减半*/
        if (target.isDefense() && (attacker.getType() == 2 || attacker.getSkillId() == 501)) {
            hurt /= 2;
        }
        if (hurt <= 0) {
            hurt = 1;
        }

        // 游说伤害减少
        hurt = (int) PetSkillProcessor.queryProcessor(SkillConst.SKILL_YOU_SHUO).effect(fight, attacker, target, hurt);

        if (hurt > target.getCurrLife()) {
            hurt = target.getCurrLife();
        }
        return hurt;
    }
    //统一的减伤处理
    public static int getHurtByReduce(int hurt,FightObject target,boolean isPlayer){
        double hurtReduce = 0.0;
        if(target.isPlayer()){
            hurtReduce += target.getRole().getChildInfo().getXian()*0.004;
            double totalCon = target.getRole().getExtendBox().getBasicAttrib().getCon() + target.getRole().getCon() + target.getRole().getExtraCon();
            hurtReduce +=totalCon/400*0.1;
            if(hurtReduce>0.9){//减伤
                hurtReduce=0.9;
            }
        }
        //所有宠物默认增加30的减伤
        if(target.isPet()){
            if(isPlayer){
                hurtReduce += 0.2;
            }else{
                hurtReduce += 0.4;
            }
            Pet pet = target.getPet();
            double js = getJs(pet);
            hurtReduce+=js;
            //如果有破防的话减伤也要被破
//            if(isPenetrate){
//                hurtReduce = hurtReduce*penetrateRate;
//            }
        }
        if(hurtReduce>=1){
            hurtReduce = 1;
        }
        hurt = (int)(hurt * (1-hurtReduce));
        return hurt;
    }
    //新增宠物减伤算法
    //如果全体加点，血量成长/1000 之后*3.0  如果3体 *2.5 如果2体 2.0  1 体 1.0
    public static double getJs(Pet pet){
        double hurtReduce = 0.0;
        //基础血量成长
        double life = pet.getLifeEffect();
        //宠物等级
        double level = pet.getLevel();
        //宠物体质
        double con = pet.getCon();
        //宠物增加体质
        double rate =(con-level)/level*0.5;

        hurtReduce =  life/1000 * (1+rate);

        return hurtReduce;
    }

    public static void main(String[] args) {
        double hurtReduce = 0.0;
        //基础血量成长
        double life = 155.0;
        //宠物等级
        double level = 115;
        //宠物体质
        double con = 575;
        //宠物增加体质
        double rate =(con-level)/level*0.5;

        hurtReduce =  life/1000 * (1+rate);

        System.out.println(hurtReduce);
    }
}